package cn.unknowpupil.service.system.impl;

import cn.unknowpupil.common.core.exceptions.HealthException;
import cn.unknowpupil.common.core.utils.StringUtils;
import cn.unknowpupil.common.core.utils.ValidateMobileUtil;
import cn.unknowpupil.domain.system.SysPost;
import cn.unknowpupil.domain.system.SysRole;
import cn.unknowpupil.domain.system.SysUser;
import cn.unknowpupil.mapper.system.SysPostMapper;
import cn.unknowpupil.mapper.system.SysRoleMapper;
import cn.unknowpupil.mapper.system.SysUserMapper;
import cn.unknowpupil.service.system.ICommonService;
import cn.unknowpupil.service.system.ISysUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created at 2020-10-16 by  w10g <br>
 * Initialize SysUser  ... <br>
 * 用户信息表 核心业务处理实现类
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Resource
    private SysPostMapper sysPostMapper;
    @Resource
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ICommonService commonService;

    /**
     * 新增
     *
     * @param sysUser {@link SysUser}  用户信息表
     * @return {@link SysUser}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(SysUser sysUser) {
        validUserParam(sysUser);

        String encode = bCryptPasswordEncoder.encode(sysUser.getPassword());
        sysUser.setPassword(encode);
        boolean save = save(sysUser);
        if (save) {
            // 新增用户岗位关联
            insertUserPost(sysUser);
            // 新增用户与角色管理
            insertUserRole(sysUser);
        }
        return save;

    }


    /**
     * 详情
     *
     * @param id {@code Long}   SysUser ID
     * @return {@link SysUser}
     */
    @Override
    public SysUser info(Long id) {
        return getById(id);
    }

    /**
     * 删除
     *
     * @param ids {@code Long}   SysUser ID
     * @return {@link SysUser}
     */
    @Override
    public boolean delete(Long[] ids) {
        for (Long id : ids) {
            if (id == 1) {
                throw new HealthException("不允许操作超级用户");
            }
        }
        List<Long> collect = Stream.of(ids).collect(Collectors.toList());
        boolean b = removeByIds(collect);
        if (b) {
            // 删除用户管理部门 角色
            baseMapper.removeUserPostRelatedness(ids);
            // 删除用户用户 角色
            baseMapper.removeUserRoleRelatedness(ids);
            return true;
        } else {
            return false;
        }
    }


    /**
     * 修改
     *
     * @param sysUser {@link SysUser}  用户信息表
     * @return {@link SysUser}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(SysUser sysUser) {
        validUserParam(sysUser);
        boolean b = updateById(sysUser);
        if (b) {
            baseMapper.removeUserPostRelatednessByUserId(sysUser.getId());
            // 新增用户岗位关联
            insertUserPost(sysUser);

            baseMapper.removeUserRoleRelatednessByUserId(sysUser.getId());
            // 新增用户与角色管理
            insertUserRole(sysUser);
        }
        return updateById(sysUser);
    }


    /**
     * 分页
     *
     * @param current {@code int} 页码
     * @param size    {@code int} 笔数
     * @param sysUser {@link SysUser}
     * @return {@code IPage<SysUser>}
     */
    @Override
    public IPage<SysUser> page(int current, int size, SysUser sysUser) {

        IPage<SysUser> page = new Page<>(current, size);
        return baseMapper.page(page, sysUser);
    }

    @Override
    public SysUser getUserByUsername(String username) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserName, username);
        return getOne(wrapper);
    }

    @Override
    public boolean changePwd(SysUser user) {
        if (StringUtils.isBlank(user.getPassword())) {
            throw new HealthException("密码未必填项");
        }
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        return super.updateById(user);
    }

    @Override
    public boolean changeStatus(SysUser user) {
        return super.updateById(user);
    }



    @Override
    public String selectUserRoleGroup(Long userId) {
        List<SysRole> list = sysRoleMapper.selectRolesByUserId(userId);
        StringBuffer idsStr = new StringBuffer();
        for (SysRole role : list) {
            idsStr.append(role.getRoleName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    @Override
    public String selectUserPostGroup(Long userId) {
        List<SysPost> list = sysPostMapper.selectPostsByUserId(userId);
        StringBuffer idsStr = new StringBuffer();
        for (SysPost post : list) {
            idsStr.append(post.getPostName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    @Override
    public boolean editProfile(SysUser user) {
        user.setUserName(null);
        validUserParam(user);

        return super.updateById(user);
    }

    @Override
    public String updateAvatar( MultipartFile file,Long userId) {
        String avatar = commonService.uploadAvatar(file);
        SysUser byId = getById(userId);
        byId.setAvatar(avatar);
        boolean b = updateById(byId);
        if(b){
            return avatar;
        }else {
            throw new HealthException("更新失败");
        }



    }

    /**
     * 新增用户与岗位管理
     *
     * @param user {@link SysUser}
     */
    private void insertUserPost(SysUser user) {
        Long[] posts = user.getPostIds();
        if (StringUtils.isNotNull(posts)) {
            baseMapper.insertUserPostRelatedness(posts,user.getId());
        }
    }

    /**
     * 新增用户与角色管理
     *
     * @param user {@link SysUser}
     */
    private void insertUserRole(SysUser user) {
        Long[] roles = user.getRoleIds();
        if (StringUtils.isNotNull(roles)) {
            baseMapper.insertUserRoleRelatedness(roles,user.getId());
        }
    }

    /**
     * 校验用户参数
     *
     * @param sysUser {@link SysUser} 用户
     * @return
     */
    private boolean validUserParam(SysUser sysUser) {
        boolean chinaPhoneLegal = ValidateMobileUtil.isChinaPhoneLegal(sysUser.getPhonenumber());
        Assert.isTrue(chinaPhoneLegal, "手机号格式不对，请重试");
        boolean result = checkUserNameUnique(sysUser);
        Assert.isTrue(result, "用户名已经存在，请重试");
        result = checkEmailUnique(sysUser);
        Assert.isTrue(result, "邮箱已经存在，请重试");
         result = checkPhoneUnique(sysUser);
        Assert.isTrue(result, "手机号已经存在，请重试");

        return result;
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkUserNameUnique(SysUser user) {
        int count = baseMapper.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, user.getUserName()));
        if (count > 0) {
            return false;
        }
        return true;
    }

    /**
     * 校验手机号是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkPhoneUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }

    /**
     * 校验邮箱称是否唯一
     *
     * @param user {@link SysUser} 用户
     * @return 结果 true 是 false 不是
     */

    public boolean checkEmailUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));

        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue()) {
            return false;
        }
        return true;
    }
}
